package cn.majingjing.core.tool;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

/**
 * @author majinding888@foxmail.com
 * @date 2016-11-2 下午5:02:47
 */
public class TmClassUtils {

	@SuppressWarnings("unchecked")
	public static <T> Class<T> loadClass(String name) throws ClassNotFoundException {
		return (Class<T>) Thread.currentThread().getContextClassLoader().loadClass(name);
	}

	public static Annotation[] getAnnotions(Class<?> clz) {
		return clz.getAnnotations();
	}

	public static Method[] getDeclaredMethods(Class<?> clz) {
		return clz.getDeclaredMethods();
	}

	public static Class<?>[] getParameterTypes(Method m) {
		return m.getParameterTypes();
	}

	public static Class<?> getReturnType(Method m) {
		return m.getReturnType();
	}

	public static String getSimpleName(Method m) {
		return m.getName();
	}

	public static Annotation[] getAnnotations(Method m) {
		return m.getAnnotations();
	}

	@SafeVarargs
	public static Set<Method> getMethods(Class<?> clz, Class<? extends Annotation>... fieldAnnotions) {
		Method[] methods = clz.getDeclaredMethods();
		Set<Method> _m = new HashSet<>();
		for (int i = 0; i < methods.length; i++) {
			if (isAnnotationPresent(methods[i], fieldAnnotions)) {
				_m.add(methods[i]);
			}
		}
		return _m;
	}

	@SafeVarargs
	public static Set<Field> getFields(Class<?> clz, Class<? extends Annotation>... fieldAnnotions) {
		Field[] fields = clz.getDeclaredFields();
		Set<Field> _f = new HashSet<>();
		for (int i = 0; i < fields.length; i++) {
			if (isAnnotationPresent(fields[i], fieldAnnotions)) {
				_f.add(fields[i]);
			}
		}
		return _f;
	}

	/**
	 * 包含继承父类的属性
	 * 
	 * @author Administrator - JingjingMa
	 * @Email <a href="majinding888@foxmail.com">majinding888@foxmail.com</a>
	 * @date 2017年4月29日 上午11:41:10
	 * @version 3.2
	 * @DevTool Created By Eclipse 4.3
	 *
	 * @param clz
	 * @param fieldAnnotions
	 * @return
	 */
	@SafeVarargs
	public static Set<Field> getAllFields(Class<?> clz, Class<? extends Annotation>... fieldAnnotions) {
		Set<Field> _f = new HashSet<>();
		do {
			_f.addAll(TmClassUtils.getFields(clz, fieldAnnotions));
			clz = clz.getSuperclass();
		} while (clz != Object.class);
		return _f;
	}

	@SafeVarargs
	public static boolean isAnnotationPresent(Class<?> clz, Class<? extends Annotation>... fieldAnnotions) {
		for (int i = 0; i < fieldAnnotions.length; i++) {
			if (!clz.isAnnotationPresent(fieldAnnotions[i])) {
				return false;
			}
		}
		return true;
	}

	@SafeVarargs
	public static boolean isAnnotationPresent(Method method, Class<? extends Annotation>... fieldAnnotions) {
		for (int i = 0; i < fieldAnnotions.length; i++) {
			if (!method.isAnnotationPresent(fieldAnnotions[i])) {
				return false;
			}
		}
		return true;
	}

	@SafeVarargs
	public static boolean isAnnotationPresent(Field field, Class<? extends Annotation>... fieldAnnotions) {
		for (int i = 0; i < fieldAnnotions.length; i++) {
			if (!field.isAnnotationPresent(fieldAnnotions[i])) {
				return false;
			}
		}
		return true;
	}

}
